#include <stdio.h>
#include <math.h>
#include "timer.h"
#include "sc.h"

#define TRIALS 1024

PixelToPixelOp()
on(in stream unsigned char *i,
    out stream unsigned char *o)
{
  *o = 255;
}

PixelToPixelOp()
p2p(in stream unsigned char *i,
    out stream unsigned char *o)
{
  *o = *i;
}

PixelLookupOp()
pl(in stream unsigned char *i,
   out stream unsigned char *o)
{
  *o = *i;
}

PixelFilterOp()
pf(in stream unsigned char *i,
   out stream unsigned char *o)
{
  *o = *i;
  push();
}

AnisoPixelToPixelOp()
ap2p(in stream unsigned char *i,
    out stream unsigned char *o)
{
  *o = *i;
}

LUTNeighbourhoodToPixelOp(in int *lutsize)
lutn2p(in stream unsigned char *i,
    out stream unsigned char *o)
{
  setLUT(0, 0, 1);
}

NeighbourhoodToPixelOp()
n2p(in stream unsigned char i[0][0],
    out stream unsigned char *o)
{
  *o = i[0][0];
}

RecursiveNeighbourhoodToPixelOp()
rn2p(in stream unsigned char i[0][0],
    out stream unsigned char o[0][0])
{
  o[0][0] = i[0][0];
}

OptStackOp2(in stream unsigned char *_init, in int *_threshold)
stk(in stream unsigned char i[0][0],
    out stream unsigned char *o)
{
  *o = i[0][0];
}

GlobalOp()
glb(in stream unsigned char i[][],
    out stream unsigned char o[][])
{
  int x, y;

  for (y=0; y < _lines; y++)
    for (x=0; x < _stride; x++)
      o[y][x] = i[y][x];
}

int MAIN(int argc, char **argv)
{
  int i;
  STREAM image, init;
  tmr_t timer = tmrInit();

  scInit(argc, argv);

  generate(scint(1024), &image);
  _multi(&image);

  on(&image, &init);
  _multi(&init);
  
  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    p2p(&image, &image);
  tmrStop(&timer);
  printf("p2p: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    pl(&image, &image);
  tmrStop(&timer);
  printf("pl: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    pf(&image, &image);
  tmrStop(&timer);
  printf("pf: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    ap2p(&image, &image);
  tmrStop(&timer);
  printf("ap2p: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    LUTNeighbourhoodToPixelOp(scint(1), lutn2p, &image, &image);
  tmrStop(&timer);
  printf("lutn2p: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    n2p(&image, &image);
  tmrStop(&timer);
  printf("n2p: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    rn2p(&image, &image);
  tmrStop(&timer);
  printf("rn2p: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    OptStackOp2(&init, scint(0), stk, &image, &image);
  tmrStop(&timer);
  printf("stk: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  tmrStart(&timer);
  for (i=0; i < TRIALS; i++)
    glb(&image, &image);
  tmrStop(&timer);
  printf("glb: %f ms\n", (double)tmrGetValueInUs(&timer)/TRIALS/1000.0);

  return scExit();
}
